// --------------------------------------------------------------------------------------------------------------------
// <copyright company="" file="SimpleMapCache.cs">
//   
// </copyright>
// <summary>
//   Simple cache implementation that uses a HashMap to store (key, value) pairs.
//   This cache is not synchronized, use {@link Cache#SynchronizedCache(Cache)}
//   if needed.
// </summary>
// 
// --------------------------------------------------------------------------------------------------------------------

namespace Lucene.Net.Util.Cache
{
    using System.Collections;

    /// <summary>
    /// Simple cache implementation that uses a HashMap to store (key, value) pairs.
    /// This cache is not synchronized, use {@link Cache#SynchronizedCache(Cache)}
    /// if needed.
    /// </summary>
    public class SimpleMapCache : Cache
    {
        /// <summary>
        /// The map.
        /// </summary>
        internal IDictionary map;

        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleMapCache"/> class.
        /// </summary>
        public SimpleMapCache()
            : this(new Hashtable())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleMapCache"/> class.
        /// </summary>
        /// <param name="map">
        /// The map.
        /// </param>
        public SimpleMapCache(IDictionary map)
        {
            this.map = map;
        }

        /// <summary>
        /// The get.
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <returns>
        /// The get.
        /// </returns>
        public override object Get(object key)
        {
            return map[key];
        }

        /// <summary>
        /// The put.
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <param name="value_Renamed">
        /// The value_ renamed.
        /// </param>
        public override void Put(object key, object value_Renamed)
        {
            map[key] = value_Renamed;
        }

        /// <summary>
        /// The close.
        /// </summary>
        public override void Close()
        {
            // NOOP
        }

        /// <summary>
        /// The contains key.
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <returns>
        /// The contains key.
        /// </returns>
        public override bool ContainsKey(object key)
        {
            // Console.WriteLine(": "+map[key]);
            return map.Contains(key);
        }

        /// <summary>
        /// Returns a Set containing all keys in this cache.
        /// </summary>
        public virtual ICollection KeySet()
        {
            return map.Keys;
        }

        /// <summary>
        /// The get synchronized cache.
        /// </summary>
        /// <returns>
        /// </returns>
        internal override Cache GetSynchronizedCache()
        {
            return new SynchronizedSimpleMapCache(this);
        }

        /// <summary>
        /// The synchronized simple map cache.
        /// </summary>
        private class SynchronizedSimpleMapCache : SimpleMapCache
        {
            /// <summary>
            /// The mutex.
            /// </summary>
            internal object mutex;

            /// <summary>
            /// The cache.
            /// </summary>
            internal SimpleMapCache cache;

            /// <summary>
            /// Initializes a new instance of the <see cref="SynchronizedSimpleMapCache"/> class.
            /// </summary>
            /// <param name="cache">
            /// The cache.
            /// </param>
            internal SynchronizedSimpleMapCache(SimpleMapCache cache)
            {
                this.cache = cache;
                this.mutex = this;
            }

            /// <summary>
            /// The put.
            /// </summary>
            /// <param name="key">
            /// The key.
            /// </param>
            /// <param name="value_Renamed">
            /// The value_ renamed.
            /// </param>
            public override void Put(object key, object value_Renamed)
            {
                lock (mutex)
                {
                    cache.Put(key, value_Renamed);
                }
            }

            /// <summary>
            /// The get.
            /// </summary>
            /// <param name="key">
            /// The key.
            /// </param>
            /// <returns>
            /// The get.
            /// </returns>
            public override object Get(object key)
            {
                lock (mutex)
                {
                    return cache.Get(key);
                }
            }

            /// <summary>
            /// The contains key.
            /// </summary>
            /// <param name="key">
            /// The key.
            /// </param>
            /// <returns>
            /// The contains key.
            /// </returns>
            public override bool ContainsKey(object key)
            {
                lock (mutex)
                {
                    return cache.ContainsKey(key);
                }
            }

            /// <summary>
            /// The close.
            /// </summary>
            public override void Close()
            {
                lock (mutex)
                {
                    cache.Close();
                }
            }

            /// <summary>
            /// The key set.
            /// </summary>
            /// <returns>
            /// </returns>
            public override ICollection KeySet()
            {
                lock (mutex)
                {
                    return cache.KeySet();
                }
            }

            /// <summary>
            /// The get synchronized cache.
            /// </summary>
            /// <returns>
            /// </returns>
            internal override Cache GetSynchronizedCache()
            {
                return this;
            }
        }
    }
}